import japa.parser.*;
import japa.parser.ast.CompilationUnit;
import japa.parser.ast.body.ClassOrInterfaceDeclaration;
import japa.parser.ast.visitor.GenericVisitorAdapter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import javax.swing.JFileChooser;
import javax.swing.JFrame;

public class NumberOfChildren {

	/**
	 * Counts the number of children a class
	 */

	// map a classname to those it extends
	static HashMap<String, String> map = new HashMap();

	public static void main(String[] args) throws Exception {

		JFileChooser fc = new JFileChooser();

		fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
		fc.showOpenDialog(new JFrame());

		// creates an input stream for the file to be parsed
		File file = fc.getSelectedFile();

		/* Directory */
		if (file.isDirectory())
			for (File child : file.listFiles()) {
				if (child.getName().endsWith(".java")) {
					CompilationUnit cu = parseFile(child);
					NOCVisitor nv = new NOCVisitor();
					nv.visit(cu, null);
					map.put((java.lang.String) nv.name, nv.extendz);
				}
			}

		/* single file */
		else {
			if (file.getName().endsWith(".java")) {
				CompilationUnit cu = parseFile(file.getAbsoluteFile());
				NOCVisitor nv = new NOCVisitor();
				nv.visit(cu, null);
				map.put((java.lang.String) nv.name, nv.extendz);
			}
		}

		for (java.lang.String entry : map.keySet()) {

			String exList = map.get(entry);

			System.out.println("Class " + entry + "extends: ");

			if (exList != null)
				System.out.println(getTree((java.lang.String) exList));
			else
				System.out.println("Object 1");

		}

	}

	public static int getTree(String leaf) {
		int count = 1;
		System.out.print(leaf + " ");
		if (map.containsKey(leaf)) {
			count = count + getTree((java.lang.String) map.get(leaf));
		}

		else {
			return 0;
		}

		return count;
	}

	/**
	 * Create a compilation for the file
	 */
	private static CompilationUnit parseFile(File f) throws ParseException,
			IOException {
		CompilationUnit cu = null;

		System.out.println("File Name " + f.getName());
		if (f.getName().endsWith(".java")) {

			FileInputStream in = new FileInputStream(f.getAbsolutePath());

			try {
				// parse the file
				cu = JavaParser.parse(in);
			} finally {
				in.close();
			}
		}

		return cu;
	}

	/**
	 * Simple visitor implementation for visiting MethodDeclaration nodes.
	 * 
	 * @param <R>
	 * @param <R>
	 * @param <A>
	 */
	private static class NOCVisitor<String> extends GenericVisitorAdapter {

		public String name;
		public java.lang.String extendz;

		@Override
		public java.lang.String visit(ClassOrInterfaceDeclaration n, Object arg) {

			name = (String) n.getName();
			if (n.getExtends() != null)
				extendz = n.getExtends().get(0).getName();

			return n.getName();

		}

	}
}
